package pers.ljf.escloud.controller.app;

import cn.hutool.core.util.RandomUtil;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import pers.ljf.escloud.common.constant.ZFileConstant;
import pers.ljf.escloud.common.dto.FileItemDTO;
import pers.ljf.escloud.common.dto.FileListDTO;
import pers.ljf.escloud.common.dto.ResultBean;
import pers.ljf.escloud.common.dto.SystemFrontConfigDTO;
import pers.ljf.escloud.common.req.FileListReq;
import pers.ljf.escloud.common.utils.FileComparator;
import pers.ljf.escloud.common.utils.FileUtils;
import pers.ljf.escloud.common.utils.StringUtils;
import pers.ljf.escloud.controller.BaseController;
import pers.ljf.escloud.dao.dto.DriveListDTO;
import pers.ljf.escloud.dao.entity.DriveConfig;
import pers.ljf.escloud.dao.entity.app.Department;
import pers.ljf.escloud.dao.entity.app.ShortLinkConfig;
import pers.ljf.escloud.dto.NewFolderForm;
import pers.ljf.escloud.dto.UploadRequest;
import pers.ljf.escloud.service.dto.Result;
import pers.ljf.escloud.service.modules.app.*;
import pers.ljf.escloud.util.MultipartFileToFile;
import pers.ljf.escloud.util.PutObjProgressListener;
import pers.ljf.escloud.util.WsSessionManager;

import javax.annotation.Resource;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 前台文件管理
 *
 * @author zhaojun
 */
@Slf4j
@RequestMapping("/app/file")
@RestController
public class AppFIleController extends BaseController {

    @Resource
    private FileService fileService;

    @Resource
    private DriveConfigService driveConfigService;

    @Resource
    private SystemConfigService systemConfigService;

    @Resource
    private DepartmentService departmentService;

    @Resource
    private EnterpriseService enterpriseService;

    private static final String domain = "http://localhost:8080/";
    @Resource
    private ShortLinkConfigService shortLinkConfigService;

    @GetMapping("/drive/list")
    public ResultBean drives() {
        List<DriveConfig> driveList = driveConfigService.listOnlyEnable();
        boolean isInstall = true;
        DriveListDTO driveListDTO = new DriveListDTO(driveList, isInstall);
        return ResultBean.success(driveListDTO);
    }

    /**
     * @param path           访问的目录
     * @param password
     * @param orderBy
     * @param orderDirection
     * @return
     * @throws Exception
     */
    @GetMapping("/list")
    public ResultBean list(@RequestParam(defaultValue = "/") String path,
                           @RequestParam(required = false) String password,
                           @RequestParam(required = false) String orderBy,
                           @RequestParam(required = false, defaultValue = "asc") String orderDirection) throws Exception {
        String curDir = getBasePath() + (path.equals("/") ? "" : path);
        Department curDept = departmentService.getOne(new QueryWrapper<Department>().eq("full_path_name", curDir));
        List<FileItemDTO> fileItemList = fileService.fileList(FileListReq.builder().client(getClient()).path(StringUtils.removeDuplicateSeparator(ZFileConstant.PATH_SEPARATOR + path + ZFileConstant.PATH_SEPARATOR)).isBase(false).build());
        List<FileItemDTO> resList = fileItemList.stream().filter(fileItemDTO -> !fileItemDTO.getName().equals("net_url2870800544618991248a04fcf12-9b80-4256-9e05-b1b2c2660066.png")).collect(Collectors.toList());
        resList.sort(new FileComparator(orderBy, orderDirection));
        SystemFrontConfigDTO config = fileService.getConfig();
        FileListDTO fileListDTO = new FileListDTO(resList, config);
        ResultBean resultBean = ResultBean.successData(fileListDTO);
        if (curDept != null) {
            resultBean.setCurDeptId(curDept.getId());
        }
        return resultBean;
    }

    /**
     * 删除文件或者文件夹
     *
     * @param path 文件key，"a.text" or "dept1/dept2"
     * @return
     */
    @PostMapping("/delete")
    public ResultBean deleteFile(String path) {
        //校验要删除的文件夹是否是部门文件夹
        if (fileService.isDeptFolder(getFullPath(path, true))) {
            return ResultBean.error("部门文件夹不可直接删除");
        }
//        if (!path.contains(".") && fileService.isFolder(getBucketName(),getClient(),getFullPath(path, true))) {
        fileService.deleteByPrefix(getUserId(), getBucketName(), getFullPath(path, false), getClient(), true);
//        } else {
//            fileService.deleteFile(getBucketName(), getFullPath(path, false), getClient());
//        }

        return ResultBean.success();
    }

    @PostMapping("/upload")
    public Result upload(UploadRequest uploadRequest) throws Exception {
        File file = null;
        try {
            Assert.isTrue(uploadRequest.getFile() != null, "要上传的文件不可为空");
            Assert.isTrue(uploadRequest.getPath() != null, "文件上传路径不可为空");
            long size = uploadRequest.getFile().getSize();
            if (size > 1024 * 1024) {
                departmentService.updateDeptSpace(Long.valueOf(uploadRequest.getCurDeptId()), size / 1024 / 1024);
                enterpriseService.updateSpace(getUserId(), size / 1024 / 1024);
            }
            //将MultipartFile转为File
            log.info("originFIleName:{}", uploadRequest.getFile().getOriginalFilename());
            file = MultipartFileToFile.multipartFileToFile(uploadRequest.getFile());
            String fileName = uploadRequest.getFile().getOriginalFilename();
            String filePath = uploadRequest.getPath().replaceFirst("/", "");
            String basePath = getBasePath();
            log.info("base path:{}", basePath);
            Assert.isTrue(StringUtils.isNotNullOrEmpty(basePath) && !basePath.startsWith("/"), "basePath路径不正确");
            log.info("upload filePath:{}", filePath);
            Assert.isTrue(filePath != null && !filePath.startsWith("/"), "文件路径格式不正确");
            log.info("upload fileName:{}", fileName);
            Assert.isTrue(StringUtils.isNotNullOrEmpty(fileName), "文件名为空");

            String objectName = getFileFullName(basePath, filePath, fileName);
            log.info("objectName:{}", objectName);
            Assert.isTrue(WsSessionManager.get(getToken()) != null, "客户端未建立websocket连接");
            PutObjectRequest request = new PutObjectRequest(getBucketName(), objectName, file).withProgressListener(new PutObjProgressListener(getToken()));
            PutObjectResult putObjectResult = getClient().putObject(request);
            log.info("res:{}", new Gson().toJson(putObjectResult));
//        } catch (Exception e) {
//            e.printStackTrace();
//            return ResultBean.error("上传失败，请检查文件格式再次尝试");
        } finally {
            MultipartFileToFile.deleteTempFile(file);
        }
        return Result.ok();
    }

    /**
     * @param basePath "/" "/123/213"
     * @param path     "/" "/21321/21"
     * @param name     "213.txt"
     * @return
     */
    private String getFileFullName(String basePath, String path, String name) {
        //如果前面不是/就累加上，是则去除当前/，去除剩下空格再累加上；不是/就累加/
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(basePath);
        if (StringUtils.isNotNullOrEmpty(path)) {
            stringBuilder.append("/").append(path);
        }
        stringBuilder.append("/").append(name);
        return stringBuilder.toString();
    }

    private String getFileFullName(String basePath, String filePath) {
        //如果前面不是/就累加上，是则去除当前/，去除剩下空格再累加上；不是/就累加/
        StringBuilder stringBuilder = new StringBuilder();
        if (basePath.endsWith("/")) {
            basePath = basePath.substring(0, basePath.length() - 1);
        }
        stringBuilder.append(basePath);
        stringBuilder.append("/");
        stringBuilder.append(filePath);
        return stringBuilder.toString();
    }

    @GetMapping("/short-link")
    @ResponseBody
    public Result shortLink(String driveId, String path) {
        // 拼接直链地址，直链访问请求路径 + 文件地址
        String fullPath = getFileFullName(getBasePath(), path).replaceFirst("/", "");

        ShortLinkConfig shortLinkConfig = shortLinkConfigService.findByUrl(fullPath);

        if (shortLinkConfig == null) {

            String randomKey;
            do {
                // 获取短链
                randomKey = RandomUtil.randomString(6);
                shortLinkConfig = shortLinkConfigService.findByKey(randomKey);
            } while (shortLinkConfig != null);

            shortLinkConfig = new ShortLinkConfig();
            shortLinkConfig.setFileKey(randomKey);
            shortLinkConfig.setUrl(fullPath);
            shortLinkConfigService.save(shortLinkConfig);
        }

        String shortUrl = StringUtils.removeDuplicateSeparator(domain + "/s/" + shortLinkConfig.getFileKey());
        return Result.ok().put("data", shortUrl);
    }

    @PostMapping("/newFolder")
    public Result newFolder(NewFolderForm form) {
        Assert.isTrue(!form.getNewFolderName().startsWith("/"), "新文件夹名称不规范");
        File tmpFile = FileUtils.getNetUrlHttps("https://ljf-gulimall.oss-cn-beijing.aliyuncs.com/img/20210607163831.png");
        String fileFullName = getFileFullName(getBasePath(), form.getPath().replaceFirst("/", ""), form.getNewFolderName() + "/net_url2870800544618991248a04fcf12-9b80-4256-9e05-b1b2c2660066.png");
        log.info("newFolderObjName:" + fileFullName);
        getClient().putObject(getBucketName(), fileFullName, tmpFile);
        return Result.ok("新建成功");
    }
}
